﻿using PARK.Common.Enum;
using PARK.Common.Extension;
using PARK.Common.Filter;
using PARK.Dependency;
using PARK.DynamicApiController;
using PARK.FriendlyException;
using Mapster;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Yitter.IdGenerator;
using PARK.Common.Helper;
using PARK.JsonSerialization;
using PARK.Welfare.Interfaces.WelfareClear;
using PARK.Welfare.Entitys;
using PARK.Common.Core.Manager;
using PARK.Welfare.Entitys.Dto.WelfareClear;
using PARK.ClayObject;
using PARK.Common.Model.NPOI;
using PARK.Common.Configuration;
using PARK.DataEncryption;
using PARK.Welfare.Entitys.Dto.WelfareClearDetail;
using PARK.System.Interfaces.System;
using PARK.SubDev.Entitys.Dto;
using Microsoft.AspNetCore.Http;
using PARK.System.Interfaces.Common;
using PARK.CardAcct.Entitys;
using PARK.System.Entitys.Permission;

namespace PARK.Welfare.WelfareClear
{
    /// <summary>
    /// 福利清零记录服务
    /// </summary>
    [ApiDescriptionSettings(Tag = "Welfare", Name = "WelfareClear", Order = 200)]
    [Route("api/welfare/[controller]")]
    public class WelfareClearService : IWelfareClearService, IDynamicApiController, ITransient
    {
        private readonly ISqlSugarRepository<WelfareClearEntity> _welfareClearRepository;
        private readonly ISqlSugarRepository<WelfareClearDetailEntity> _welfareClearDetailRepository;
        private readonly IBillRullService _billRuleService;
        private readonly SqlSugarScope _db;
        private readonly IUserManager _userManager;
        private readonly IFileService _fileService;

        /// <summary>
        /// 初始化一个<see cref="WelfareClearService"/>类型的新实例
        /// </summary>
        public WelfareClearService(
            ISqlSugarRepository<WelfareClearEntity> welfareClearRepository,
            ISqlSugarRepository<WelfareClearDetailEntity> welfareClearDetailRepository,
            IBillRullService billRuleService,
            IFileService fileService,
            IUserManager userManager)
        {
            _welfareClearRepository = welfareClearRepository;
            _db = _welfareClearRepository.Context;
            _fileService = fileService;
            _welfareClearDetailRepository = welfareClearDetailRepository;
            _billRuleService = billRuleService;
            _userManager = userManager;
        }

        /// <summary>
        /// 获取福利清零
        /// </summary>
        /// <param name="id">参数</param>
        /// <returns></returns>
        [HttpGet("{id}")]
        public async Task<dynamic> GetInfo(string id)
        {
            var entity = await _db.Queryable<WelfareClearEntity>().FirstAsync(p => p.BillId == id);
            var output = entity.Adapt<WelfareClearInfoOutput>();
            var welfareClearDetailList = await _db.Queryable<WelfareClearDetailEntity>().Where(w => w.BillId == entity.BillId).ToListAsync();
            output.welfareClearDetailList = welfareClearDetailList.Adapt<List<WelfareClearDetailInfoOutput>>();
            return output;
        }

        /// <summary>
		/// 获取福利清零记录列表
		/// </summary>
		/// <param name="input">请求参数</param>
		/// <returns></returns>
        [HttpGet("")]
        public async Task<dynamic> GetList([FromQuery] WelfareClearListQueryInput input)
        {
            var userInfo = await _userManager.GetUserInfo();
            var sidx = input.sidx == null ? "DbDate" : input.sidx;

            //发放日期
            List<string> queryBillDate = input.inputBillDate != null ? input.inputBillDate.Split(',').ToObeject<List<string>>() : null;
            DateTime? startBilldate = queryBillDate != null ? Ext.GetDateTime(queryBillDate.First()) : null;
            DateTime? endBilldate = queryBillDate != null ? Ext.GetDateTime(queryBillDate.Last()) : null;
            //清零时段
            List<string> querybegendDate = input.inputbegendDate != null ? input.inputbegendDate.Split(',').ToObeject<List<string>>() : null;
            DateTime? startbegdate = querybegendDate != null ? Ext.GetDateTime(querybegendDate.First()) : null;
            DateTime? endenddate = querybegendDate != null ? Ext.GetDateTime(querybegendDate.Last()) : null;
            var data = await _db.Queryable<WelfareClearEntity>()
                .Where(p => p.CompanyId.Equals(userInfo.companyId))//权限
                                                                   //关键字查询
                .WhereIF(!input.keyword.IsNullOrEmpty(), p => p.BillCode.Contains(input.keyword) || p.AuditUserName.Contains(input.keyword))
                //日期查询
                .WhereIF(queryBillDate != null, a => a.BillDate >= new DateTime(startBilldate.ToDate().Year, startBilldate.ToDate().Month, startBilldate.ToDate().Day, 0, 0, 0))
                .WhereIF(queryBillDate != null, a => a.BillDate <= new DateTime(endBilldate.ToDate().Year, endBilldate.ToDate().Month, endBilldate.ToDate().Day, 23, 59, 59))
                //清零时段查询
                .WhereIF(querybegendDate != null, a => a.ClearDate >= new DateTime(startbegdate.ToDate().Year, startbegdate.ToDate().Month, startbegdate.ToDate().Day, 0, 0, 0))
                .WhereIF(querybegendDate != null, a => a.ClearDate <= new DateTime(endenddate.ToDate().Year, endenddate.ToDate().Month, endenddate.ToDate().Day, 23, 59, 59))
                .Select(it => new WelfareClearListOutput
                {
                    billId = it.BillId,
                    billCode = it.BillCode,
                    billDate = Convert.ToDateTime(it.BillDate).ToString("yyyy-MM-dd"),
                    clearDate = Convert.ToDateTime(it.ClearDate).ToString("yyyy-MM"),
                    //clearDate = Convert.ToDateTime(it.ClearDate).ToString("yyyy-MM-dd"),
                    wagetotal = it.Wagetotal,
                    wageRows = it.WageRows,
                    summary = it.Summary,
                    IsAudit = it.IsAudit,
                    AuditUser = it.AuditUser,
                    AuditUserName = it.AuditUserName,
                    AuditDate = Convert.ToDateTime(it.AuditDate).ToString("yyyy-MM-dd HH:mm:ss"),
                    DbDate = Convert.ToDateTime(it.DbDate).ToString("yyyy-MM-dd HH:mm:ss"),
                }).MergeTable().OrderBy(sidx + " " + input.sort).ToPagedListAsync(input.currentPage, input.pageSize);
            return PageResult<WelfareClearListOutput>.SqlSugarPageResult(data);
        }

        /// <summary>
        /// 新建福利清零
        /// </summary>
        /// <param name="input">参数</param>
        /// <returns></returns>
        [HttpPost("")]
        public async Task Create([FromBody] WelfareClearCrInput input)
        {
            var userInfo = await _userManager.GetUserInfo();
            var entity = input.Adapt<WelfareClearEntity>();
            entity.BillId = YitIdHelper.NextId().ToString();
            entity.BillCode = await _billRuleService.GetBillNumber("flql");
            DateTime enddate = Convert.ToDateTime(entity.ClearDate).AddDays(1);
            DateTime dt = DateTime.Parse(Convert.ToDateTime(enddate).ToString("yyyy-MM-dd") + " 00:00:00");
            //获得本月月初时间
            var startMonth = dt.AddDays(1 - dt.Day);
            //获得本月月末时间
            DateTime s = DateTime.Parse(Convert.ToDateTime(enddate).ToString("yyyy-MM-dd") + " 23:59:59");
            DateTime ss = s.AddDays(1 - s.Day);
            var endMonth = ss.AddMonths(1).AddDays(-1);
            entity.ClearDate = endMonth;

            var clearlist = await _db.Queryable<WelfareClearEntity>().Where(t => t.CompanyId.Equals(userInfo.companyId)).ToListAsync();
            foreach (var item in clearlist)
            {
                if (item.ClearDate >= endMonth)
                {
                    throw PARKException.Oh("该清零日期之前已经清零,无需再次清零！");
                }
            }

            entity.CreateUser = userInfo.userId;
            entity.CreateUserName = userInfo.userName;
            entity.CreateDate = DateTime.Now;
            entity.IsAudit = 1;
            entity.AuditUser = userInfo.userId;
            entity.AuditUserName = userInfo.userName;
            entity.AuditDate = DateTime.Now;
            entity.CompanyId = userInfo.companyId;
            entity.CompanyName = userInfo.companyName;
            try
            {
                //开启事务
                _db.BeginTran();
                int _WageRows = 0;
                decimal _Wagetotal = 0;
                var welfareClearDetailEntityList = input.welfareClearDetailList.Adapt<List<WelfareClearDetailEntity>>();
                var welfarelist = new List<WelfareClearDetailEntity>();
                if (welfareClearDetailEntityList != null)
                {
                    foreach (var item in welfareClearDetailEntityList)
                    {
                        _WageRows++;
                        _Wagetotal += item.Balance;
                        //item.OldDetailsid = item.Detailsid;
                        item.BillId = entity.BillId;
                        item.BillCode = entity.BillCode;
                        item.BillDate = entity.BillDate;
                        item.DbDate = entity.BillDate;
                        item.IsAccounted = 1;
                        item.AccountedDate = DateTime.Now;
                        item.BussKind = 2;
                        item.CompanyId = userInfo.companyId;
                        item.CompanyName = userInfo.companyName;
                        ////清空福利明细
                        //var _WelfareDetail = await _db.Queryable<WelfareDetailEntity>().FirstAsync(t => t.Detailsid == item.OldDetailsid);
                        //_WelfareDetail.Balance = 0;
                        //await _db.Updateable(_WelfareDetail).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
                        //卡户福利余额减值
                        var _Employee = await _db.Queryable<EmployeeEntity>().FirstAsync(t => t.EmployeeId == item.EmployeeId);
                        _Employee.WelfareBalance -= item.Balance;
                        await _db.Updateable(_Employee).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
                        item.Detailsid = YitIdHelper.NextId().ToString();
                        welfarelist.Add(item);
                    }
                    if (welfarelist != null && welfarelist.Count > 0)
                        await _db.Insertable(welfarelist).ExecuteCommandAsync();
                }
                //新增福利清零记录
                entity.WageRows = _WageRows;
                entity.Wagetotal = _Wagetotal;
                entity.CompanyId = userInfo.companyId;
                entity.CompanyName = userInfo.companyName;
                var newEntity = await _db.Insertable(entity).IgnoreColumns(ignoreNullColumn: true).ExecuteReturnEntityAsync();
                //关闭事务
                _db.CommitTran();
            }
            catch (Exception ex)
            {
                //回滚事务
                _db.RollbackTran();
                throw PARKException.Oh(ErrorCode.COM1000);
            }
        }

        /// <summary>
        /// 更新福利清零
        /// </summary>
        /// <param name="id">主键</param>
        /// <param name="input">参数</param>
        /// <returns></returns>
        [HttpPut("{id}")]
        public async Task Update(string id, [FromBody] WelfareClearUpInput input)
        {
            var userInfo = await _userManager.GetUserInfo();
            var entity = input.Adapt<WelfareClearEntity>();
            try
            {
                //开启事务
                _db.BeginTran();

                //更新福利清零记录
                await _db.Updateable(entity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();

                //清空原有数据
                await _db.Deleteable<WelfareClearDetailEntity>().Where(u => u.BillId == id).ExecuteCommandAsync();
                //新增新数据
                var welfareDetailEntityList = input.welfareClearDetailList.Adapt<List<WelfareClearDetailEntity>>();
                if (welfareDetailEntityList != null)
                {
                    foreach (var item in welfareDetailEntityList)
                    {
                        item.Detailsid = YitIdHelper.NextId().ToString();
                        item.BillId = entity.BillId;
                        item.CompanyId = userInfo.companyId;
                        item.CompanyName = userInfo.companyName;
                    }
                    await _db.Insertable(welfareDetailEntityList).ExecuteCommandAsync();
                }

                //关闭事务
                _db.CommitTran();
            }
            catch (Exception)
            {
                //回滚事务
                _db.RollbackTran();
                throw PARKException.Oh(ErrorCode.COM1001);
            }
        }
        /// <summary>
        /// 审核福利清零
        /// </summary>
        /// <returns></returns>
        [HttpDelete("WelAudit/{id}")]
        public async Task WelAudit(string id)
        {
            var userInfo = await _userManager.GetUserInfo();
            var entity = await _db.Queryable<WelfareClearEntity>().FirstAsync(p => p.BillId == id);
            _ = entity ?? throw PARKException.Oh(ErrorCode.COM1005);
            try
            {
                //开启事务
                _db.BeginTran();
                entity.IsAudit = 1;
                entity.AuditUser = userInfo.userId;
                entity.AuditUserName = userInfo.userName;
                entity.AuditDate = DateTime.Now;
                entity.CompanyId = userInfo.companyId;
                entity.CompanyName = userInfo.companyName;
                var detaillist = await _db.Queryable<WelfareClearDetailEntity>().Where(p => p.BillId == id).ToListAsync();
                foreach (var item in detaillist)
                {
                    item.IsAccounted = 1;
                    item.AccountedDate = DateTime.Now;
                    item.CompanyId = userInfo.companyId;
                    item.CompanyName = userInfo.companyName;
                    await _db.Updateable(item).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
                    var _Employee = await _db.Queryable<EmployeeEntity>().FirstAsync(t => t.EmployeeId == item.EmployeeId);
                    _Employee.WelfareBalance += item.Amount;
                    await _db.Updateable(_Employee).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
                }
                //更新福利清零记录
                await _db.Updateable(entity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
                //关闭事务
                _db.CommitTran();
            }
            catch (Exception)
            {
                //回滚事务
                _db.RollbackTran();
                throw PARKException.Oh(ErrorCode.COM1001);
            }
        }
        /// <summary>
        /// 删除福利清零
        /// </summary>
        /// <returns></returns>
        [HttpDelete("{id}")]
        public async Task Delete(string id)
        {
            var entity = await _db.Queryable<WelfareClearEntity>().FirstAsync(p => p.BillId == id);
            _ = entity ?? throw PARKException.Oh(ErrorCode.COM1005);
            try
            {
                //开启事务
                _db.BeginTran();

                //删除福利清零记录
                await _db.Deleteable<WelfareClearEntity>().Where(d => d.BillId == id).ExecuteCommandAsync();

                //清空子表数据
                await _db.Deleteable<WelfareClearDetailEntity>().Where(u => u.BillId == id).ExecuteCommandAsync();

                //关闭事务
                _db.CommitTran();
            }
            catch (Exception)
            {
                //回滚事务
                _db.RollbackTran();
                throw PARKException.Oh(ErrorCode.COM1002);
            }
        }

        #region 导出Excel
        /// <summary>
        /// 获取清零记录无分页列表
        /// </summary>
        /// <param name="input">请求参数</param>
        /// <returns></returns>
        [NonAction]
        public async Task<dynamic> GetNoPagingList([FromQuery] WelfareClearListQueryInput input)
        {
            var userInfo = await _userManager.GetUserInfo();
            var sidx = input.sidx == null ? "billId" : input.sidx;
            var data = await _db.Queryable<WelfareClearEntity>()
                .Where(p => p.CompanyId.Equals(userInfo.companyId))//权限
                .Select(it => new WelfareClearListOutput
                {
                    billId = it.BillId,
                    billCode = it.BillCode,
                    billDate = Convert.ToDateTime(it.BillDate).ToString("yyyy-MM-dd"),
                    clearDate = Convert.ToDateTime(it.ClearDate).ToString("yyyy-MM-dd"),
                    wagetotal = it.Wagetotal,
                    wageRows = it.WageRows,
                    summary = it.Summary,
                    IsAudit = it.IsAudit,
                    AuditUser = it.AuditUser,
                    AuditUserName = it.AuditUserName,
                    AuditDate = Convert.ToDateTime(it.AuditDate).ToString("yyyy-MM-dd HH:mm:ss"),
                    DbDate = Convert.ToDateTime(it.DbDate).ToString("yyyy-MM-dd HH:mm:ss"),
                }).MergeTable().OrderBy(sidx + " " + input.sort).ToListAsync();
            return data;
        }

        /// <summary>
        /// 导出清零记录
        /// </summary>
        /// <param name="input">请求参数</param>
        /// <returns></returns>
        [HttpGet("Actions/Export")]
        public async Task<dynamic> Export([FromQuery] WelfareClearListQueryInput input)
        {
            var userInfo = await _userManager.GetUserInfo();
            var exportData = new List<WelfareClearListOutput>();
            var exportDataNew = new List<WelfareClearListOutput>();

            var entity = input.Adapt<WelfareBillEntity>();

            if (input.dataType == 0)
            {
                var data = Clay.Object(await this.GetList(input));
                exportData = data.Solidify<PageResult<WelfareClearListOutput>>().list;
            }
            else
            {
                exportData = await this.GetNoPagingList(input);
            }

            foreach (WelfareClearListOutput item in exportData)
            {
                exportDataNew.Add(item);
            }

            List<ParamsModel> paramList = "[{\"value\":\"单据编号\",\"field\":\"billCode\"},{\"value\":\"单据日期\",\"field\":\"billDate\"},{\"value\":\"清零截止时间\",\"field\":\"clearDate\"},{\"value\":\"清零福利总额\",\"field\":\"wagetotal\"},{\"value\":\"福利总条数\",\"field\":\"wageRows\"},{\"value\":\"备注信息\",\"field\":\"summary\"},]".ToList<ParamsModel>();
            ExcelConfig excelconfig = new ExcelConfig();
            excelconfig.FileName = userInfo.organizeName + "_" + "福利清零记录" + DateTime.Now.ToString("yyyyMMddHHmmss") + ".xls";
            excelconfig.HeadFont = "微软雅黑";
            excelconfig.HeadPoint = 10;
            excelconfig.IsAllSizeColumn = true;
            excelconfig.ColumnModel = new List<ExcelColumnModel>();
            List<string> selectKeyList = input.selectKey.Split(',').ToList();
            foreach (var item in selectKeyList)
            {
                var isExist = paramList.Find(p => p.field == item);
                if (isExist != null)
                {
                    excelconfig.ColumnModel.Add(new ExcelColumnModel() { Column = isExist.field, ExcelColumn = isExist.value });
                }
            }
            var addPath = FileVariable.TemporaryFilePath + excelconfig.FileName;
            ExcelExportHelper<WelfareClearListOutput>.Export(exportDataNew, excelconfig, addPath);
            var fileName = _userManager.UserId + "|" + addPath + "|xls";
            var output = new
            {
                name = excelconfig.FileName,
                //url = "wwwroot/Resources/TemporaryFile/" + excelconfig.FileName
                url = "api/file/Download?encryption=" + DESCEncryption.Encrypt(fileName, "JNPF") //"wwwroot/Template/TemporaryFile/" + excelconfig.FileName //
            };
            return output;
        }
        #endregion

        #region 导出明细
        /// <summary>
        /// 获取清零明细记录无分页列表
        /// </summary>
        /// <param name="input">请求参数</param>
        /// <returns></returns>
        [NonAction]
        public async Task<dynamic> GetNoPagingdetList([FromQuery] WelfareClearListQueryInput input)
        {
            var userInfo = await _userManager.GetUserInfo();
            var sidx = input.sidx == null ? "jobNo" : input.sidx;
            var data = await _db.Queryable<WelfareClearDetailEntity>()
                .Where(p => p.CompanyId.Equals(userInfo.companyId))//权限
                .Where(p => p.BillId.Equals(input.billId))
                .Select(it => new WelfareClearDetailListOutput
                {
                    billId = it.BillId,
                    jobNo = it.JobNo,
                    reallName = it.ReallName,
                    departName = it.DepartName,
                    cardNo = it.CardNo,
                    catCardNo = it.CatCardNo,
                    summary = it.Summary,
                    balance = it.Balance,
                }).MergeTable().OrderBy(sidx + " ").ToListAsync();
            return data;
        }

        /// <summary>
        /// 导出清零明细记录
        /// </summary>
        /// <param name="input">请求参数</param>
        /// <returns></returns>
        [HttpGet("Actions/Exportdet")]
        public async Task<dynamic> Exportdet([FromQuery] WelfareClearListQueryInput input)
        {
            var userInfo = await _userManager.GetUserInfo();
            var exportData = new List<WelfareClearDetailListOutput>();
            var exportDataNew = new List<WelfareClearDetailListOutput>();

            exportData = await this.GetNoPagingdetList(input);

            foreach (WelfareClearDetailListOutput item in exportData)
            {
                exportDataNew.Add(item);
            }

            List<ParamsModel> paramList = "[{\"value\":\"工号\",\"field\":\"jobNo\"},{\"value\":\"姓名\",\"field\":\"reallName\"},{\"value\":\"部门\",\"field\":\"departName\"},{\"value\":\"卡号\",\"field\":\"cardNo\"},{\"value\":\"长安通卡号\",\"field\":\"catCardNo\"},{\"value\":\"清零金额\",\"field\":\"balance\"},{\"value\":\"备注信息\",\"field\":\"summary\"},]".ToList<ParamsModel>();
            ExcelConfig excelconfig = new ExcelConfig();
            excelconfig.FileName = userInfo.organizeName + "_" + "福利清零明细记录" + DateTime.Now.ToString("yyyyMMddHHmmss") + ".xls";
            excelconfig.HeadFont = "微软雅黑";
            excelconfig.HeadPoint = 10;
            excelconfig.IsAllSizeColumn = true;
            excelconfig.ColumnModel = new List<ExcelColumnModel>();
            List<string> selectKeyList = input.selectKey.Split(',').ToList();
            foreach (var item in selectKeyList)
            {
                var isExist = paramList.Find(p => p.field == item);
                if (isExist != null)
                {
                    excelconfig.ColumnModel.Add(new ExcelColumnModel() { Column = isExist.field, ExcelColumn = isExist.value });
                }
            }
            var addPath = FileVariable.TemporaryFilePath + excelconfig.FileName;
            ExcelExportHelper<WelfareClearDetailListOutput>.Export(exportDataNew, excelconfig, addPath);
            var fileName = _userManager.UserId + "|" + addPath + "|xls";
            var output = new
            {
                name = excelconfig.FileName,
                //url = "wwwroot/Resources/TemporaryFile/" + excelconfig.FileName
                url = "api/file/Download?encryption=" + DESCEncryption.Encrypt(fileName, "JNPF") //"wwwroot/Template/TemporaryFile/" + excelconfig.FileName //
            };
            return output;
        }
        #endregion

    }
}
